package repositorios;

import entidades.Usuario;
import excessoes.DAOException;
import interfaces.InterfaceUsuarioDAO;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.exception.ConstraintViolationException;

/**
 *
 * @author marcelo
 */
public class UsuarioDAOHibernate implements InterfaceUsuarioDAO
{
    private Session session;
    /*
    protected String sqlState;
    
        protected String getSQLState(Throwable exception) {  
        this.sqlState = null;  
        if (exception.getCause() instanceof ConstraintViolationException) {  
            ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception.getCause();  
            sqlState = constraintViolationException.getSQLState();  
        }  
        return sqlState;  
    }  
    */
    public void setSessao(Session session) {
        this.session = session;
    }
    
    //TODO o hibernate nao conseguira fazer a carga caso seja passado o Usuario no parametro, tem que ser diretamente a chave (integer)
    @Override
    public Usuario carregarUsuario(Integer id) throws DAOException {
        return (Usuario) this.session.get(Usuario.class, id);
    }
    
    //Retorna o maior ou último ID 
    @Override
    public Integer retornaUltimoID()
    {
        Criteria criteria = session.createCriteria(Usuario.class);
        Integer maxId = (Integer) criteria.setProjection(Projections.max("id")).uniqueResult();
        return maxId;
    }
    
    @Override
    public Usuario carregarUsuarioPorSaram(Integer saram) throws DAOException 
    {
        Criteria criteria = session.createCriteria(Usuario.class);
	criteria.add(Restrictions.eq("saram", saram));
        //this.session.clear();
        return (Usuario) criteria.uniqueResult();
    }
    
    @Override
    public void salvarUsuario(Usuario usuario) throws DAOException
    {
        try {
            this.session.save(usuario);
        }
        catch (ConstraintViolationException e) {
            throw new DAOException("O campo digitado já existe no banco de dados!");
        }
    }

    @Override
    public void atualizarUsuario(Usuario usuario) throws DAOException
    {
        try
        {
        Integer id = usuario.getIdusuario();
        if (id == null || id == 0)
        {
            Usuario usuarioId = this.carregarUsuario(id);
            usuarioId.setIdusuario(id);
            this.session.evict(id);
        }
        this.session.clear();
        //this.session.merge(usuario);
        //this.session.flush();
        this.session.update(usuario);
        }
        catch (ConstraintViolationException e) {
            //if (e.getCause() instanceof ConstraintViolationException) {
                //FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "O campo digitado já existe no banco de dados!", "O campo digitado já existe no banco de dados!"));
                throw new DAOException("O campo digitado já existe no banco de dados!");
            //}
            
        }
    }
    
    @Override
    public void excluirUsuario(Usuario usuario) throws DAOException 
    {
        try {
            this.session.delete(usuario);
        }
        catch (ConstraintViolationException e) {
            throw new DAOException("Erro:\n" + e.getConstraintName());
        }
    }
    
    @Override
    public Usuario buscarPorLogin(String login) 
    {
	Criteria criteria = session.createCriteria(Usuario.class);
	criteria.add(Restrictions.eq("login", login));
        //this.session.clear();
        return (Usuario) criteria.uniqueResult();
    }
    
    @Override
    public Usuario buscarPorEmailComercial(String email) 
    {
        Criteria criteria = session.createCriteria(Usuario.class);
        criteria.createAlias("pessoa", "pe");
	criteria.add(Restrictions.eq("pe.emailComercial", email));
        //this.session.clear();
        return (Usuario) criteria.uniqueResult();
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public List<Usuario> buscarPorListaLogin(String login) 
    {
	Criteria criteria = session.createCriteria(Usuario.class);
	criteria.add(Restrictions.eq("login", login));
        //this.session.clear();
        return criteria.list();
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public List<Usuario> buscarPorListaSaram(Integer saram) 
    {
	Criteria criteria = session.createCriteria(Usuario.class);
	criteria.add(Restrictions.eq("saram", saram));
        //this.session.clear();
        return criteria.list();
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public List<Usuario> listarUsuario() 
    {
        /*
        Criteria criteria = this.session.createCriteria(Usuario.class);
        criteria.addOrder((Order.asc("saram")));
        return criteria.list();
        */
        Criteria criteria = this.session.createCriteria(Usuario.class);
        criteria.createAlias("pessoa", "pe").addOrder(Order.asc("pe.nome"));  
        return criteria.list();
    }

    @Override
    public Usuario buscarPorSaram(Integer saram) {
        Criteria criteria = session.createCriteria(Usuario.class);
	criteria.add(Restrictions.eq("saram", saram));
        //this.session.clear();
        return (Usuario) criteria.uniqueResult();
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public Object totalUsuarios()
    {
        String hql="select count(*) from usuario";
        Query consulta = this.session.createSQLQuery(hql);
        return consulta.uniqueResult();
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public Object totalUsuariosAtivos()
    {
        String hql="select count(*) from usuario where ATIVO IN ('T', 'Y', 'y', 't')";
        Query consulta = this.session.createSQLQuery(hql);
        return consulta.uniqueResult();
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public Object totalUsuariosInativos()
    {
        String hql="select count(*) from usuario where ATIVO IN ('N', 'F', 'f', 'n')";
        Query consulta = this.session.createSQLQuery(hql);
        return consulta.uniqueResult();
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<String> listarEmailAdministradores() 
    {
        String hql = "select distinct pe.email_comercial from pessoa pe, usuario usu where usu.idusuario = pe.idusuario and usu.recebe_email_aviso in ('t', 'T')";
        Query consulta = this.session.createSQLQuery(hql);
        return consulta.list();
    }
}